package org.hamster.common;

import java.util.Objects;

public class TokenString implements CharSequence {
    private final String original;
    private final String token;

    /**
     * Constructs a TokenString, stripping leading and trailing whitespace from the input.
     * The original string is preserved.
     *
     * @param token the input string, may be null
     */
    public TokenString(String token) {
        this.original = token == null ? "" : token;
        this.token = this.original.strip();
    }

    /**
     * Returns the length of the stripped token string.
     *
     * @return the number of characters in the stripped token
     */
    @Override
    public int length() {
        return token.length();
    }

    /**
     * Returns the character at the specified index of the stripped token string.
     *
     * @param index the index of the character to return
     * @return the character at the specified index
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    @Override
    public char charAt(int index) {
        return token.charAt(index);
    }

    /**
     * Returns a new TokenString that is a subsequence of this sequence.
     *
     * @param start the start index, inclusive
     * @param end the end index, exclusive
     * @return a new TokenString representing the subsequence
     * @throws IndexOutOfBoundsException if start or end are out of range
     */
    @Override
    public CharSequence subSequence(int start, int end) {
        return new TokenString(token.substring(start, end));
    }

    /**
     * Returns the stripped token string.
     *
     * @return the stripped token string
     */
    @Override
    public String toString() {
        return token;
    }

    /**
     * Returns the original, unstripped string.
     *
     * @return the original string
     */
    public String getOriginal() {
        return original;
    }

    /**
     * Compares this TokenString to another object for equality, ignoring case and leading/trailing whitespace.
     *
     * @param obj the object to compare to
     * @return true if the objects are equal ignoring case and whitespace, false otherwise
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj instanceof TokenString other) {
            return token.equalsIgnoreCase(other.token);
        }
        if (obj instanceof CharSequence cs) {
            return token.equalsIgnoreCase(cs.toString().strip());
        }
        return false;
    }

    /**
     * Returns a hash code for this TokenString, ignoring case.
     *
     * @return the hash code
     */
    @Override
    public int hashCode() {
        return token.toLowerCase().hashCode();
    }
}